home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume20 / index-db / part02 < prev    next >
Encoding:
Internet Message Format  |  1989-10-23  |  16.7 KB

  1. Subject:  v20i057:  Maintain multiple databases of textual data, Part02/02
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Dave Curry <davy@riacs.edu>
  7. Posting-number: Volume 20, Issue 57
  8. Archive-name: index-db/part02
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 2 (of 2)."
  17. # Contents:  screen.c
  18. # Wrapped by rsalz@papaya.bbn.com on Tue Oct 24 12:09:02 1989
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f 'screen.c' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'screen.c'\"
  22. else
  23. echo shar: Extracting \"'screen.c'\" \(14727 characters\)
  24. sed "s/^X//" >'screen.c' <<'END_OF_FILE'
  25. X#ifndef lint
  26. Xstatic char *RCSid = "$Header: /u5/davy/progs/index/RCS/screen.c,v 1.1 89/08/09 11:06:53 davy Exp $";
  27. X#endif
  28. X/*
  29. X * screen.c - screen management routines.
  30. X *
  31. X * David A. Curry
  32. X * Research Institute for Advanced Computer Science
  33. X * Mail Stop 230-5
  34. X * NASA Ames Research Center
  35. X * Moffett Field, CA 94035
  36. X * davy@riacs.edu
  37. X *
  38. X * $Log:    screen.c,v $
  39. X * Revision 1.1  89/08/09  11:06:53  davy
  40. X * Initial revision
  41. X * 
  42. X */
  43. X#include <sys/param.h>
  44. X#include <signal.h>
  45. X#include <curses.h>
  46. X#include <stdio.h>
  47. X#include "defs.h"
  48. X
  49. Xstatic int    screen_inited = 0;    /* for use with set/reset modes    */
  50. X
  51. X/*
  52. X * Menu used by disp_entries routine.
  53. X */
  54. Xstatic char    *disp_menu[] = {
  55. X    "<RET> = next entry                   \"d\" = delete this entry\n",
  56. X    "\"-\" = previous entry                 \"e\" = edit this entry\n",
  57. X    "\"q\" = return to main menu",
  58. X    0
  59. X};
  60. X
  61. X/*
  62. X * prompt_str - prompt the user for a string.
  63. X */
  64. Xprompt_str(row, col, promptstr, answer)
  65. Xchar *promptstr, *answer;
  66. Xint row, col;
  67. X{
  68. X    char *line;
  69. X    int len, col0;
  70. X    register int c, i, j;
  71. X
  72. X    /*
  73. X     * Print the prompt at (row,col).
  74. X     */
  75. X    mvaddstr(row, col, promptstr);
  76. X    refresh();
  77. X
  78. X    /*
  79. X     * Calculate "column zero", which is at the right
  80. X     * end of the prompt.
  81. X     */
  82. X    col += strlen(promptstr);
  83. X    line = answer;
  84. X    col0 = col;
  85. X    len = 0;
  86. X
  87. X    /*
  88. X     * Read characters till we get what we want.  The user
  89. X     * is allowed basic EMACS-style line editing.
  90. X     */
  91. X    while ((c = getchar()) != EOF) {
  92. X        switch (c) {
  93. X        case CTRL(a):            /* beginning of line    */
  94. X            col = col0;
  95. X            break;
  96. X        case CTRL(b):            /* back character    */
  97. X            if (col > col0)
  98. X                col--;
  99. X            break;
  100. X        case CTRL(d):            /* delete character    */
  101. X            /*
  102. X             * If there's stuff in the string,
  103. X             * delete this character.
  104. X             */
  105. X            if (len) {
  106. X                /*
  107. X                 * Calculate string position of
  108. X                 * character to delete.
  109. X                 */
  110. X                i = col - col0;
  111. X
  112. X                /*
  113. X                 * Shuffle the string "left" one
  114. X                 * place.
  115. X                 */
  116. X                while (i < len) {
  117. X                    line[i] = line[i+1];
  118. X                    i++;
  119. X                }
  120. X
  121. X                /*
  122. X                 * Delete the character on the screen.
  123. X                 */
  124. X                len -= 1;
  125. X                delch();
  126. X            }
  127. X
  128. X            break;
  129. X        case CTRL(e):            /* end of line        */
  130. X            col = col0 + len;
  131. X            break;
  132. X        case CTRL(f):            /* forward character    */
  133. X            if ((col - col0) < len)
  134. X                col++;
  135. X            break;
  136. X        case CTRL(h):            /* backspace delete    */
  137. X        case '\177':
  138. X            /*
  139. X             * If there's stuff in the string,
  140. X             * delete the character.
  141. X             */
  142. X            if (len) {
  143. X                /*
  144. X                 * Calculate position in string of
  145. X                 * character to be deleted.
  146. X                 */
  147. X                i = col - col0 - 1;
  148. X
  149. X                /*
  150. X                 * Shuffle the string "left" one place.
  151. X                 */
  152. X                while (i < len) {
  153. X                    line[i] = line[i+1];
  154. X                    i++;
  155. X                }
  156. X
  157. X                len -= 1;
  158. X
  159. X                /*
  160. X                 * Delete the character on the screen.
  161. X                 */
  162. X                move(row, --col);
  163. X                delch();
  164. X            }
  165. X            break;
  166. X        case CTRL(k):            /* kill line        */
  167. X            /*
  168. X             * Clear the string.
  169. X             */
  170. X            if (len) {
  171. X                i = col - col0;
  172. X
  173. X                line[i] = '\0';
  174. X                len = i;
  175. X
  176. X                clrtoeol();
  177. X            }
  178. X            break;
  179. X        case CTRL(l):            /* redraw screen    */
  180. X            wrefresh(curscr);
  181. X            break;
  182. X        case '\n':            /* return the string    */
  183. X            line[len] = '\0';
  184. X            return;
  185. X        default:            /* regular character    */
  186. X            /*
  187. X             * If it's the user's line-kill character,
  188. X             * we'll accept that to kill the line too.
  189. X             */
  190. X            if (c == _tty.sg_kill) {
  191. X                move(row, col0);
  192. X                clrtoeol();
  193. X                col = col0;
  194. X
  195. X                *line = '\0';
  196. X                len = 0;
  197. X            }
  198. X            else {
  199. X                /*
  200. X                 * If it's a printable character,
  201. X                 * insert it into the string.
  202. X                 */
  203. X                if ((c >= ' ') && (c < '\177')) {
  204. X                    /*
  205. X                     * Calculate position of character
  206. X                     * in string.
  207. X                     */
  208. X                    i = col - col0;
  209. X
  210. X                    /*
  211. X                     * If we have to, move the
  212. X                     * string "right" one place
  213. X                     * to insert the character.
  214. X                     */
  215. X                    if (i < len) {
  216. X                        for (j = len; j >= i; j--)
  217. X                            line[j+1] = line[j];
  218. X                    }
  219. X
  220. X                    line[i] = c;
  221. X                    len += 1;
  222. X                    col++;
  223. X
  224. X                    /*
  225. X                     * Insert the character on the
  226. X                     * screen.
  227. X                     */
  228. X                    insch(c);
  229. X
  230. X                }
  231. X            }
  232. X            break;
  233. X        }
  234. X
  235. X        /*
  236. X         * Move the cursor.
  237. X         */
  238. X        move(row, col);
  239. X        refresh();
  240. X    }
  241. X}
  242. X
  243. X/*
  244. X * prompt_char - prompt the user for a single character, which must
  245. X *         be one of the ones in the "valid" string.
  246. X */
  247. Xprompt_char(row, col, promptstr, valid)
  248. Xchar *promptstr, *valid;
  249. Xint row, col;
  250. X{
  251. X    char *index();
  252. X    register int c;
  253. X
  254. X    /*
  255. X     * Print the prompt.
  256. X     */
  257. X    mvaddstr(row, col, promptstr);
  258. X    clrtoeol();
  259. X    refresh();
  260. X
  261. X    /*
  262. X     * Read characters...
  263. X     */
  264. X    while ((c = getchar()) != EOF) {
  265. X        /*
  266. X         * If it's not a valid one, beep
  267. X         * and get another one.
  268. X         */
  269. X        if (index(valid, c) == NULL) {
  270. X            putc('\007', stdout);
  271. X            fflush(stdout);
  272. X            continue;
  273. X        }
  274. X
  275. X        /*
  276. X         * Add the character to the
  277. X         * screen, and return it.
  278. X         */
  279. X        addch(c);
  280. X        refresh();
  281. X
  282. X        return(c);
  283. X    }
  284. X}
  285. X
  286. X/*
  287. X * main_menu - we dispatch to database functions from here.
  288. X */
  289. Xmain_menu(dbname)
  290. Xchar *dbname;
  291. X{
  292. X    register char c;
  293. X
  294. X    /*
  295. X     * Set tty modes.
  296. X     */
  297. X    set_modes();
  298. X
  299. X    /*
  300. X     * Forever...
  301. X     */
  302. X    for (;;) {
  303. X        /*
  304. X         * Clear the screen.
  305. X         */
  306. X        clear();
  307. X
  308. X        /*
  309. X         * Print the name of the database and number of
  310. X         * entries.
  311. X         */
  312. X        mvprintw(0, 0, "Database: %s  (%d entries)", dbname,
  313. X             dbentries);
  314. X
  315. X        /*
  316. X         * Mention whether or not it's modified.
  317. X         */
  318. X        if (dbmodified)
  319. X            addstr("  [modified]");
  320. X
  321. X        /*
  322. X         * Print the choices.
  323. X         */
  324. X        mvaddstr(3, 8, "a - Add new entry to database");
  325. X        mvaddstr(4, 8, "f - Find entry in database");
  326. X        mvaddstr(5, 8, "r - Read database entry by entry");
  327. X        mvaddstr(6, 8, "s - Save modifications, do not exit");
  328. X        mvaddstr(7, 8, "q - Save modifications, exit");
  329. X        mvaddstr(8, 8, "x - Exit");
  330. X
  331. X        /*
  332. X         * Get one of the choices.
  333. X         */
  334. X        c = prompt_char(10, 0, "Command: ", "afqrsx\014");
  335. X
  336. X        /*
  337. X         * Dispatch the choice to the proper
  338. X         * database function.
  339. X         */
  340. X        switch (c) {
  341. X        case 'a':
  342. X            add_entry();
  343. X            break;
  344. X        case 'f':
  345. X            find_entry();
  346. X            break;
  347. X        case 'q':
  348. X            save_bye(dbname);
  349. X            break;
  350. X        case 'r':
  351. X            read_db();
  352. X            break;
  353. X        case 's':
  354. X            save_db(dbname);
  355. X            break;
  356. X        case 'x':
  357. X            byebye();
  358. X            break;
  359. X        case CTRL(l):            /* redraw screen    */
  360. X            wrefresh(curscr);
  361. X            break;
  362. X        }
  363. X    }
  364. X}
  365. X
  366. X/*
  367. X * disp_entries - display all database entries with DB_PRINT set, and
  368. X *          let the user choose what to do with the entry.
  369. X */
  370. Xdisp_entries()
  371. X{
  372. X    int first, save = -1;
  373. X    register int c, i, j;
  374. X
  375. X    /*
  376. X     * Clear the screen.
  377. X     */
  378. Xtop:    clear();
  379. X
  380. X    /*
  381. X     * Print the names of the fields.
  382. X     */
  383. X    for (i = 0; i < idx.idx_nlines; i++) {
  384. X        mvprintw(i, 0, "%s%s", idx.idx_lines[i],
  385. X             idx.idx_lines[i][0] ? ":" : "");
  386. X    }
  387. X
  388. X    /*
  389. X     * Print the menu.
  390. X     */
  391. X    for (i=0; disp_menu[i] != NULL; i++)
  392. X        mvaddstr(idx.idx_nlines+i+2, 10, disp_menu[i]);
  393. X
  394. X    /*
  395. X     * Find the first printable entry, and save its
  396. X     * index in first.
  397. X     */
  398. X    for (first=0; first < dbentries; first++) {
  399. X        if (db[first].db_flag & DB_PRINT)
  400. X            break;
  401. X    }
  402. X
  403. X    /*
  404. X     * Set current entry to either the first one
  405. X     * or the saved one.
  406. X     */
  407. X    if (save < 0)
  408. X        i = first;
  409. X    else
  410. X        i = save;
  411. X
  412. X    /*
  413. X     * Until we run out of entries...
  414. X     */
  415. X    while (i < dbentries) {
  416. X        /*
  417. X         * Print the entry.
  418. X         */
  419. X        for (j=0; j < idx.idx_nlines; j++) {
  420. X            move(j, idx.idx_maxlen + 2);
  421. X            clrtoeol();
  422. X            addstr(db[i].db_lines[j]);
  423. X        }
  424. X
  425. X        /*
  426. X         * Print current/total entry numbers.
  427. X         */
  428. X        mvprintw(idx.idx_nlines+7, COLS-15, "%5d/%-5d", i+1,
  429. X             dbentries);
  430. X
  431. X        /*
  432. X         * See what they want to do with this entry.
  433. X         */
  434. X        c = prompt_char(idx.idx_nlines+6, 0, "Command: ",
  435. X                "-deq\n\014");
  436. X
  437. X        /*
  438. X         * Dispatch the command...
  439. X         */
  440. X        switch (c) {
  441. X        case '\n':            /* go to next entry    */
  442. X            /*
  443. X             * Save this one.
  444. X             */
  445. X            save = i;
  446. X
  447. X            /*
  448. X             * Advance to next printable one.
  449. X             */
  450. X            for (i++; i < dbentries; i++) {
  451. X                if (db[i].db_flag & DB_PRINT)
  452. X                    break;
  453. X            }
  454. X
  455. X            break;
  456. X        case '-':            /* go to previous entry    */
  457. X            /*
  458. X             * Save this one.
  459. X             */
  460. X            save = i;
  461. X
  462. X            /*
  463. X             * Hunt for the previous printable one.
  464. X             */
  465. X            for (i--; i >= 0; i--) {
  466. X                if (db[i].db_flag & DB_PRINT)
  467. X                    break;
  468. X            }
  469. X
  470. X            if (i < 0)
  471. X                i = first;
  472. X
  473. X            break;
  474. X        case 'd':            /* delete entry        */
  475. X            /*
  476. X             * See if they really want to delete it.
  477. X             * If so, mark it as not valid, and
  478. X             * re-sort the database.
  479. X             *
  480. X             * Because of the save variable, next
  481. X             * time through we'll print the last
  482. X             * one they looked at.
  483. X             */
  484. X            if (del_entry(&db[i])) {
  485. X                db[i].db_flag &= ~(DB_VALID | DB_PRINT);
  486. X                qsort(db, dbentries, sizeof(struct dbfile),
  487. X                      dbsort);
  488. X                dbmodified = 1;
  489. X                dbentries--;
  490. X                goto top;
  491. X            }
  492. X
  493. X            save = i;
  494. X            goto top;
  495. X        case 'e':            /* edit entry        */
  496. X            /*
  497. X             * Let them edit the entry.
  498. X             */
  499. X            if (edit_entry(&db[i], "modified"))
  500. X                dbmodified = 1;
  501. X
  502. X            save = i;
  503. X            goto top;
  504. X        case 'q':            /* return to main menu    */
  505. X            return;
  506. X        case '\014':            /* redraw screen    */
  507. X            break;
  508. X        }
  509. X    }
  510. X}
  511. X
  512. X/*
  513. X * edit_entry - allow the user to edit a database entry.
  514. X */
  515. Xedit_entry(entry, word)
  516. Xstruct dbfile *entry;
  517. Xchar *word;
  518. X{
  519. X    int *len;
  520. X    int col0;
  521. X    char *line;
  522. X    char tbuf[64];
  523. X    char *malloc();
  524. X    struct dbfile tmp;
  525. X    register int c, i, j, row, col;
  526. X
  527. X    /*
  528. X     * Figure out where "column zero" is, to the
  529. X     * right of the longest field name.
  530. X     */
  531. X    col0 = idx.idx_maxlen + 2;
  532. X
  533. X    /*
  534. X     * Clear the screen.
  535. X     */
  536. X    clear();
  537. X
  538. X    /*
  539. X     * Print the field names.
  540. X     */
  541. X    for (row = 0; row < idx.idx_nlines; row++) {
  542. X        mvprintw(row, 0, "%s%s", idx.idx_lines[row],
  543. X             idx.idx_lines[row][0] ? ":" : "");
  544. X    }
  545. X
  546. X    /*
  547. X     * Allocate some space in a temporary entry, and copy
  548. X     * the entry to be edited into it.  This way they can
  549. X     * abort the edit.
  550. X     */
  551. X    for (i=0; i < idx.idx_nlines; i++) {
  552. X        /*
  553. X         * Allocate memory for this line.
  554. X         */
  555. X        if ((tmp.db_lines[i] = malloc(BUFSIZ)) == NULL) {
  556. X            error("%s: out of memory.\n", pname, 0, 0, 0);
  557. X            exit(1);
  558. X        }
  559. X
  560. X        /*
  561. X         * Save the length of the entry, zero the
  562. X         * memory.
  563. X         */
  564. X        tmp.db_lens[i] = entry->db_lens[i];
  565. X        bzero(tmp.db_lines[i], BUFSIZ);
  566. X
  567. X        /*
  568. X         * Copy and print the line from the entry.
  569. X         */
  570. X        if (entry->db_lines[i]) {
  571. X            strcpy(tmp.db_lines[i], entry->db_lines[i]);
  572. X            mvaddstr(i, col0, entry->db_lines[i]);
  573. X        }
  574. X    }
  575. X
  576. X    col = col0;
  577. X    row = 0;
  578. X
  579. X    move(row, col);
  580. X    refresh();
  581. X
  582. X    /*
  583. X     * Now let them edit the entry.  We provide the basic EMACS-style
  584. X     * control characters.
  585. X     */
  586. X    while ((c = getchar()) != EOF) {
  587. X        /*
  588. X         * Get the current line and line length.
  589. X         */
  590. X        line = tmp.db_lines[row];
  591. X        len = &tmp.db_lens[row];
  592. X
  593. X        switch (c) {
  594. X        case CTRL(a):            /* beginning of line    */
  595. X            col = col0;
  596. X            break;
  597. X        case CTRL(b):            /* back character    */
  598. X            if (col > col0)
  599. X                col--;
  600. X            break;
  601. X        case CTRL(d):            /* delete character    */
  602. X            if (*len) {
  603. X                /*
  604. X                 * Calculate position of character
  605. X                 * in string.
  606. X                 */
  607. X                i = col - col0;
  608. X
  609. X                /*
  610. X                 * Shuffle the string to the "left".
  611. X                 */
  612. X                while (i < *len) {
  613. X                    line[i] = line[i+1];
  614. X                    i++;
  615. X                }
  616. X
  617. X                *len -= 1;
  618. X
  619. X                /*
  620. X                 * Delete the character on the screen.
  621. X                 */
  622. X                delch();
  623. X            }
  624. X
  625. X            break;
  626. X        case CTRL(e):            /* end of line        */
  627. X            col = col0 + *len;
  628. X            break;
  629. X        case CTRL(f):            /* forward character    */
  630. X            if ((col - col0) < *len)
  631. X                col++;
  632. X            break;
  633. X        case CTRL(h):            /* backspace delete    */
  634. X        case '\177':
  635. X            if (*len) {
  636. X                /*
  637. X                 * Calculate position of character to
  638. X                 * delete.
  639. X                 */
  640. X                i = col - col0 - 1;
  641. X
  642. X                /*
  643. X                 * Shuffle string "left".
  644. X                 */
  645. X                while (i < *len) {
  646. X                    line[i] = line[i+1];
  647. X                    i++;
  648. X                }
  649. X
  650. X                *len -= 1;
  651. X
  652. X                /*
  653. X                 * Delete the character from the screen.
  654. X                 */
  655. X                move(row, --col);
  656. X                delch();
  657. X            }
  658. X            break;
  659. X        case CTRL(k):            /* kill line        */
  660. X            /*
  661. X             * Kill the line.
  662. X             */
  663. X            if (*len) {
  664. X                i = col - col0;
  665. X
  666. X                line[i] = '\0';
  667. X                *len = i;
  668. X
  669. X                clrtoeol();
  670. X            }
  671. X            break;
  672. X        case CTRL(l):            /* redraw screen    */
  673. X            wrefresh(curscr);
  674. X            break;
  675. X        case CTRL(n):            /* next line        */
  676. X            /*
  677. X             * Wrap around to the top if necessary.
  678. X             */
  679. X            if (++row >= idx.idx_nlines)
  680. X                row = 0;
  681. X
  682. X            /*
  683. X             * If nothing in this column, move to
  684. X             * nearest non-empty column.
  685. X             */
  686. X            if ((col - col0) > tmp.db_lens[row])
  687. X                col = col0 + tmp.db_lens[row];
  688. X            break;
  689. X        case CTRL(p):            /* previous line    */
  690. X            /*
  691. X             * Wrap around if necessary.
  692. X             */
  693. X            if (--row < 0)
  694. X                row = idx.idx_nlines - 1;
  695. X
  696. X            /*
  697. X             * If nothing in this column, move to
  698. X             * nearest non-empty column.
  699. X             */
  700. X            if ((col - col0) > tmp.db_lens[row])
  701. X                col = col0 + tmp.db_lens[row];
  702. X            break;
  703. X        case CTRL([):            /* save entry        */
  704. X            /*
  705. X             * Prompt for whether to save the entry.
  706. X             */
  707. X            sprintf(tbuf, "Save %s entry in database? ", word);
  708. X            c = prompt_char(idx.idx_nlines+2, 0, tbuf, "YyNn\n");
  709. X
  710. X            /*
  711. X             * See what they said.
  712. X             */
  713. X            switch (c) {
  714. X            case '\n':        /* never mind        */
  715. X                move(idx.idx_nlines+2, 0);
  716. X                clrtoeol();
  717. X                break;
  718. X            case 'Y':        /* save entry        */
  719. X            case 'y':
  720. X                /*
  721. X                 * Copy the temporary entry into the real
  722. X                 * entry.
  723. X                 */
  724. X                for (i=0; i < idx.idx_nlines; i++) {
  725. X                    if (entry->db_lines[i])
  726. X                        free(entry->db_lines[i]);
  727. X
  728. X                    entry->db_lines[i] = savestr(tmp.db_lines[i]);
  729. X                    entry->db_lens[i] = tmp.db_lens[i];
  730. X                    free(tmp.db_lines[i]);
  731. X                }
  732. X
  733. X                return(1);
  734. X            case 'N':        /* don't save entry    */
  735. X            case 'n':
  736. X                /*
  737. X                 * Free temporary memory.
  738. X                 */
  739. X                for (i=0; i < idx.idx_nlines; i++)
  740. X                    free(tmp.db_lines[i]);
  741. X                return(0);
  742. X            }
  743. X            break;
  744. X        case '\n':            /* go to next line    */
  745. X            /*
  746. X             * Wrap around if necessary.
  747. X             */
  748. X            if (++row >= idx.idx_nlines)
  749. X                row = 0;
  750. X            col = col0;
  751. X            break;
  752. X        default:            /* something else    */
  753. X            /*
  754. X             * If it's the user's kill character, we'll
  755. X             * accept that to delete the line too.
  756. X             */
  757. X            if (c == _tty.sg_kill) {
  758. X                move(row, col0);
  759. X                clrtoeol();
  760. X                col = col0;
  761. X
  762. X                *line = '\0';
  763. X                *len = 0;
  764. X            }
  765. X            else {
  766. X                /*
  767. X                 * If it's a printable character, insert
  768. X                 * it into the string.
  769. X                 */
  770. X                if ((c >= ' ') && (c < '\177')) {
  771. X                    /*
  772. X                     * Calculate character position.
  773. X                     */
  774. X                    i = col - col0;
  775. X
  776. X                    /*
  777. X                     * If necessary, move the string
  778. X                     * to the "right" to insert the
  779. X                     * character.
  780. X                     */
  781. X                    if (i < *len) {
  782. X                        for (j = *len; j >= i; j--)
  783. X                            line[j+1] = line[j];
  784. X                    }
  785. X
  786. X                    line[i] = c;
  787. X                    *len += 1;
  788. X                    col++;
  789. X
  790. X                    /*
  791. X                     * Insert the character on the
  792. X                     * screen.
  793. X                     */
  794. X                    insch(c);
  795. X                }
  796. X            }
  797. X            break;
  798. X        }
  799. X
  800. X        /*
  801. X         * Move to the current row/column.
  802. X         */
  803. X        move(row, col);
  804. X        refresh();
  805. X    }
  806. X}
  807. X
  808. X/*
  809. X * reset_modes - restore tty modes to their original state.
  810. X */
  811. Xreset_modes()
  812. X{
  813. X    /*
  814. X     * No need.
  815. X     */
  816. X    if (!screen_inited)
  817. X        return;
  818. X
  819. X    screen_inited = 0;
  820. X
  821. X    /*
  822. X     * Move to bottom of screen.
  823. X     */
  824. X    move(LINES-1, 0);
  825. X    refresh();
  826. X
  827. X    /*
  828. X     * Restore modes.
  829. X     */
  830. X    nocbreak();
  831. X    echo();
  832. X
  833. X    /*
  834. X     * Turn curses "off".
  835. X     */
  836. X    endwin();
  837. X
  838. X    signal(SIGQUIT, SIG_DFL);
  839. X    signal(SIGINT, SIG_DFL);
  840. X}
  841. X
  842. X/*
  843. X * set_modes - set tty modes to what we want.
  844. X */
  845. Xset_modes()
  846. X{
  847. X    /*
  848. X     * Already done.
  849. X     */
  850. X    if (screen_inited)
  851. X        return;
  852. X
  853. X    screen_inited = 1;
  854. X
  855. X    /*
  856. X     * Ignore signals.
  857. X     */
  858. X    signal(SIGQUIT, SIG_IGN);
  859. X    signal(SIGINT, SIG_IGN);
  860. X
  861. X    /*
  862. X     * Turn "curses" on, turn echo off, turn cbreak on.
  863. X     */
  864. X    initscr();
  865. X    noecho();
  866. X    cbreak();
  867. X}
  868. X
  869. END_OF_FILE
  870. if test 14727 -ne `wc -c <'screen.c'`; then
  871.     echo shar: \"'screen.c'\" unpacked with wrong size!
  872. fi
  873. # end of 'screen.c'
  874. fi
  875. echo shar: End of archive 2 \(of 2\).
  876. cp /dev/null ark2isdone
  877. MISSING=""
  878. for I in 1 2 ; do
  879.     if test ! -f ark${I}isdone ; then
  880.     MISSING="${MISSING} ${I}"
  881.     fi
  882. done
  883. if test "${MISSING}" = "" ; then
  884.     echo You have unpacked both archives.
  885.     rm -f ark[1-9]isdone
  886. else
  887.     echo You still need to unpack the following archives:
  888.     echo "        " ${MISSING}
  889. fi
  890. ##  End of shell archive.
  891. exit 0
  892.